package com.forestar.xzk.file;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class FileUtils
  {

    public static final String BLANK = "";
    public static final String POINT = ".";

    private static String screenageDir;

    private static String sdcardscreenageDir;
    private final static int BUFFER = 1024;
    private final static String TAG = "FileUtils";

    public static long getFileSize(String path)
      {
        if (TextUtils.isEmpty(path))
          {
            return -1;
          }
        return getFileSize(new File(path));
      }

    public static long getFileSize(File f)
      {
        if (f == null || !f.exists())
          {
            return -1;
          }
        long size = 0;
        if (f.isDirectory())
          {
            File[] dirFileList = f.listFiles();
            for (File item : dirFileList)
              size = size + getFileSize(item);
          } else
          {
            if (f.exists())
              {
                FileInputStream fis = null;
                try
                  {
                    fis = new FileInputStream(f);
                    size = fis.available();
                    fis.close();
                  } catch (FileNotFoundException e)
                  {
                    e.printStackTrace();
                  } catch (IOException e)
                  {
                    e.printStackTrace();
                  }
              }
          }
        return size;
      }

    public static String formetFileSize(long fileS)
      {// 转换文件大小
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        if (fileS < 1024)
          {
            fileSizeString = df.format(fileS) + "B";
          } else if (fileS < 1048576)
          {
            fileSizeString = df.format(fileS / 1024.0) + "K";
          } else if (fileS < 1073741824)
          {
            fileSizeString = df.format(fileS / 1024.0 / 1024) + "M";
          } else
          {
            fileSizeString = df.format(fileS / 1024.0 / 1024 / 1024) + "G";
          }
        return fileSizeString;
      }

    /**
     * 得到文件的扩展名
     *
     * @param uri 文件名或者文件uri
     * @return 返回文件的扩展名，如果文件名是null则返回null 如果文件没有扩展名则返回空
     */
    public static String getExtension(String uri)
      {
        if (uri == null)
          {
            return null;
          }
        int dot = uri.lastIndexOf(POINT);
        if (dot >= 0)
          {
            return uri.substring(dot);
          } else
          {
            return BLANK;
          }
      }

    public static String getScreenageDir()
      {
        return screenageDir;
      }

    public static void setScreenageDir(String screenageDir)
      {
        FileUtils.screenageDir = screenageDir;
      }

    public static String getSdcardscreenageDir()
      {
        return sdcardscreenageDir;
      }

    public static void setSdcardscreenageDir(String sdcardscreenageDir)
      {
        FileUtils.sdcardscreenageDir = sdcardscreenageDir;
      }

    /**
     * 返回当前路径下的所有文件夹的路径列表
     *
     * @return 取得当前路径下的所有文件夹的路径列表
     */
    public static ArrayList<File> getCurrentDirList(String filePath)
      {
        ArrayList<File> file_list = new ArrayList<File>();
        File[] files = (new File(filePath)).listFiles();
        for (File _file : files)
          {
            if (_file.isDirectory() && _file.getName() != "." && _file.getName() != "..")
              {
                file_list.add(_file);
              }
          }
        return file_list;
      }


    /**
     * 获取文件中的内容，每一行对应list中的一个元素
     *
     * @param file
     * @return
     */
    public static List<String> getFileLineList(File file)
      {
        List<String> lines = new ArrayList<>();
        BufferedReader br = null;
        //StringBuffer sb = new StringBuffer();
        try
          {
            InputStreamReader read = new InputStreamReader(new FileInputStream(file), "utf-8");
            br = new BufferedReader(read);
            //br = new BufferedReader(new FileReader(file),"gbk");
            String line = null;
            while ((line = br.readLine()) != null)
              {
                //sb.append(line);
                lines.add(line);
              }
          } catch (Exception e)
          {
            e.printStackTrace();
          } finally
          {
            try
              {
                if (br != null)
                  {
                    br.close();
                  }
              } catch (Exception e2)
              {
                e2.printStackTrace();
              }
          }
        return lines;
      }

    public static boolean isExists(String path)
      {
        File f = new File(path);
        return f.exists();
      }

    /**
     * 复制excel到sdcard
     *
     * @param assetsPath
     * @param sdCardPath
     * @param excelName
     * @return
     */
    public static boolean copyExcelToSdCard(Context context, String assetsPath, String sdCardPath, String excelName)
      {
        byte[] data = new byte[BUFFER];
        try
          {
            BufferedInputStream bis = new BufferedInputStream(context.getAssets().open(assetsPath));
            File file = new File(sdCardPath + "/" + excelName);
            if (!file.exists())
              {
                file.createNewFile();
              }
            int read;
            FileOutputStream fos = new FileOutputStream(file, true);
            while ((read = bis.read(data, 0, BUFFER)) != -1)
              fos.write(data, 0, read);
            bis.close();
            fos.close();
            return true;
          } catch (IOException e)
          {
            e.printStackTrace();
            return false;
          }
      }

    public static boolean deleteFile(String fileName)
      {
        File file = new File(fileName);
        if (file.exists() && file.isFile())
          {
            return file.delete();
          }
        return false;
      }

    public static void upDatamzmap(String xmlPath, String zdbName)
      {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try
          {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(new File(xmlPath));
            document.normalize();
            NodeList nl = document.getElementsByTagName("DataSource");
            for (int i = 0; i < nl.getLength(); i++)
              {
                Element element = (Element) nl.item(i);
                NodeList childrenNodes = element.getChildNodes();
                for (int j = 0; j < childrenNodes.getLength(); j++)
                  {
                    if (childrenNodes.item(j).getNodeType() == Node.ELEMENT_NODE)
                      {
                        Element childNode = (Element) childrenNodes.item(j);
                        if (childNode.getAttribute("name").equals("file"))
                          {
                            childNode.setTextContent(zdbName);
                          }
                      }
                  }
              }
            DOMSource source = new DOMSource(document);
            File f = new File(xmlPath);
            StreamResult result = new StreamResult(new FileOutputStream(f));//PrintWriter
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.transform(source, result);
          } catch (ParserConfigurationException e)
          {
            e.printStackTrace();
          } catch (SAXException e)
          {
            e.printStackTrace();
          } catch (IOException e)
          {
            e.printStackTrace();
          } catch (TransformerConfigurationException e)
          {
            e.printStackTrace();
          } catch (TransformerException e)
          {
            e.printStackTrace();
          }
      }

    /**
     * 复制单个文件
     *
     * @param srcPath  String 原文件路径
     * @param destPath String 复制后路径
     * @return boolean
     */
    public static boolean copyFile(String srcPath, String destPath)
      {
        boolean result = false;
        InputStream inStream = null;
        FileOutputStream fs = null;
        try
          {
            File srcFile = new File(srcPath);
            if (srcFile.exists())//文件存在时
              {
                int readLength = 0;
                inStream = new FileInputStream(srcPath); //读入原文件
                fs = new FileOutputStream(destPath);
                byte[] buffer = new byte[1024 * 10];
                while ((readLength = inStream.read(buffer)) != -1)
                  {
                    fs.write(buffer, 0, readLength);
                  }
                fs.flush();
                result = true;
              }
          } catch (Exception e)
          {
            e.printStackTrace();
          } finally
          {
            if (inStream != null)
              {
                try
                  {
                    inStream.close();
                  } catch (IOException e)
                  {
                    e.printStackTrace();
                  }
              }
            if (fs != null)
              {
                try
                  {
                    fs.close();
                  } catch (IOException e)
                  {
                    e.printStackTrace();
                  }
              }
          }

        return result;
      }

    //删除文件夹和文件夹里面的文件
    public static void deleteDir(final String pPath)
      {
        File dir = new File(pPath);
        deleteDirWihtFile(dir);
      }

    private static void deleteDirWihtFile(File dir)
      {
        if (dir == null || !dir.exists() || !dir.isDirectory())
          return;
        for (File file : dir.listFiles())
          {
            if (file.isFile())
              file.delete(); // 删除所有文件
            else if (file.isDirectory())
              deleteDirWihtFile(file); // 递规的方式删除文件夹
          }
        dir.delete();// 删除目录本身
      }

    /**
     * @param str  要保存的字符串
     * @param file 目标文件
     * @return
     * @Description: 把字符串保存到文件里
     */
    public static boolean saveFileFromString(String str, File file)
      {
        if (file == null)
          return false;
        FileOutputStream fout = null;
        try
          {
            fout = new FileOutputStream(file, true);
          } catch (FileNotFoundException e)
          {
            e.printStackTrace();
            return false;
          }
        try
          {
            fout.write(str.getBytes("UTF-8"));
            fout.close();
          } catch (IOException e)
          {
            e.printStackTrace();
            return false;
          }
        return true;
      }

    /**
     * @param str 要保存的字符串
     * @param dir 目标文件目录
     * @return
     * @Description: 把字符串保存到文件里
     */
    public static boolean saveFile2FromString(String str, File dir, String filename)
      {
        if (dir == null)
          return false;
        FileOutputStream fout = null;
        File file = new File(dir, filename);
        try
          {
            if (!file.exists())
              {
                file.createNewFile();
              }
            fout = new FileOutputStream(file);
          } catch (Exception e)
          {
            Log.e(TAG, "Exception:" + e.getMessage());
            return false;
          }
        try
          {
            fout.write(str.getBytes("UTF-8"));
            fout.close();
          } catch (IOException e)
          {
            //e.printStackTrace();
            return false;
          }
        return true;
      }

    /**
     * @param dir 目标文件目录
     * @return
     * @Description: 把字符串保存到文件里
     */
    public static boolean saveFile2FromJSON(JSONObject jsonObject, File dir, String filename)
      {
        if (dir == null)
          return false;
        FileOutputStream fout = null;
        File file = new File(dir, filename);
        try
          {
            if (!file.exists())
              {
                file.createNewFile();
              }
            fout = new FileOutputStream(file);
          } catch (Exception e)
          {
            Log.e(TAG, "Exception:" + e.getMessage());
            return false;
          }
        try
          {
            PrintStream printStream = new PrintStream(fout);
            printStream.print(jsonObject);
            printStream.close();
            fout.close();
          } catch (IOException e)
          {
            //e.printStackTrace();
            return false;
          }
        return true;
      }

    public static String writeFile2String(File file)
      {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        writeFile2OutputStream(file, out);
        return new String(out.toByteArray());
      }

    public static void writeFile2OutputStream(File file, OutputStream out)
      {
        writeFile2OutputStream(file, out, 1024);
      }

    public static void writeFile2OutputStream(File file, OutputStream out, int bufferSize)
      {
        long fileSize = file.length();
        if (fileSize == 0)
          {
            return;
          }
        int outBuffSize = bufferSize;
        if (fileSize < bufferSize)
          {
            outBuffSize = (int) fileSize;
          }
        byte[] buffer = new byte[outBuffSize];
        int readLen;
        try
          {
            FileInputStream fin = new FileInputStream(file);
            while ((readLen = fin.read(buffer)) != -1)
              {
                out.write(buffer, 0, readLen);
                out.flush();
                buffer = new byte[outBuffSize];
              }
            out.close();
            fin.close();
          } catch (IOException e)
          {
            e.printStackTrace();
          }

      }
  }
